//map interface for adapte different maps, such as stl map, unordered_map, multimap
//unordered_multimap, or boost, poco, and so on....
//important!!! this interface give equal_range just for multi-pre map
//andycai_sc implement 2011-04-17

#ifndef IGMAP_H
#define IGMAP_H

#include <cassert>

//-----------------GMap interface declare-------------------------------------

template<typename Key, typename Value>
class GMap
{
public:
    virtual ~GMap() {}

    class Iterator
    {
    public:
        virtual ~Iterator() {}
		virtual Iterator* clone() = 0;
        virtual const Key& getKey() = 0;
        virtual Value& getValue() = 0;
        virtual Iterator& operator++() = 0;
        virtual Iterator& operator++(int) = 0;
        virtual Iterator& operator--() { return *this; }
        virtual Iterator& operator--(int) { return *this; }
        virtual bool operator==(const Iterator&) const = 0;
        virtual bool operator!=(const Iterator&) const = 0;
    protected:
        Iterator() {}
    };

    class IteratorPtr
    {
    public:
		IteratorPtr(Iterator* it = 0) : m_it(it)
        {
        }
        IteratorPtr(const IteratorPtr& ip)
        {
            m_it = ip.m_it->clone();
        }
        ~IteratorPtr()
        {
			delete m_it;
        }

        IteratorPtr& operator=(const IteratorPtr& ip)
        {
            m_it = ip.m_it->clone();
			return *this;
        }

        Iterator* get() { return m_it; }

        Iterator* operator->() { return m_it; }
        Iterator& operator*() const { return *m_it; }

        bool operator==(const IteratorPtr& ip) const { return *(*this) == *ip; }
        bool operator!=(const IteratorPtr& ip) const { return *(*this) != *ip; }

        IteratorPtr& operator++()
        {
            *(*this)++;
            return *this;
        }

        IteratorPtr& operator++(int)
        {
            ++(*(*this));
            return *this;
        }

        IteratorPtr& operator--()
        {
            *(*this)--;
            return *this;
        }

        IteratorPtr& operator--(int)
        {
            --(*(*this));
            return *this;
        }

    private:
        Iterator* m_it;
    };

    typedef typename GMap<Key, Value>::IteratorPtr IterPtr;

    struct Range
    {
        Range() : first(0), last(0) {}
        Range(const IterPtr& first_, const IterPtr& last_) : first(first_), last(last_)
        {
        }
        IterPtr first;
        IterPtr last;
    };

    virtual IterPtr insert(const Key& key,
                        const Value& value) = 0;

    virtual int erase(const Key& key) = 0;
    virtual void erase(IterPtr position) = 0;

    virtual IterPtr find(const Key& key) = 0;

    virtual IterPtr begin() = 0;
    virtual IterPtr end() = 0;
    //just multi-pre map can support this interface
    virtual Range equal_range(const Key& key) { return Range(); }

protected:
    GMap() {}
};

#endif
